#include <string.h>
#include <stdio.h>
#include "sys_freq.h"
#include "wrapper.h"
#include "if_v.h"
#include "ov2732_drv.h"
#include "board_sensor.h"
#include "mipi_function.h"

extern int ov2732_init_rgb(i2c_dev_t *i2c, uint32_t dev_addr);
extern int isp_config(int isp_id, imageFormat_t *in, imageFormat_t *out);
extern uint8_t* iva_facereco_ir_get_buffer(uint32_t port_index, uint32_t buf_index);
extern uint8_t *iva_facereco_temp_get_buffer(void);
sensorScenario_t TX510_sensor_defConfig[IFV_SENSOR_TYPE_MAX] = {
                                                { SENSOR_EXPO_INDOOR,
                                                 MIPI_0,
                                                 ISP_0,
                                                 LED_LIGHT_TYPE_IR,
                                                 0,
                                                 if_vReConfigSensorLed},
                                               { SENSOR_EXPO_INDOOR,
                                                MIPI_1,
                                                ISP_1,
                                                LED_LIGHT_TYPE_RGB,
                                                0,
                                                if_vReConfigSensorLed}
                                                };

int g_irSensorLeftCapMode = 0;
int g_irSensorRightCapMode = 0;


const float c1  =  10.0f;
const float c2  = 100.0f;

extern uint8_t *g_vis_buffer[];
extern int g_vis_buffer_num;

void isp_rgb_buffer_reconfig(int ispIdx)
{
    // int i=0;
    if (!g_vis_buffer_num){

        printf("rgb sensor config buffer error.\n");
        return;

     }

    if(g_vis_buffer[0])
        isp_reg_write(ispIdx, MI_SP_Y_BASE_AD,  (uint32_t)g_vis_buffer[0]);
    if(g_vis_buffer[1])
        isp_reg_write(ispIdx, MI_SP_Y_BASE_AD2,  (uint32_t)g_vis_buffer[1]);
    if(g_vis_buffer[2])
        isp_reg_write(ispIdx, MI_SP_Y_BASE_AD3,  (uint32_t)g_vis_buffer[2]);
    
}

#if 0
int camera_ov2732_rgb_init()
{
    TSM_VI_INFO_S stViInfo = {0};
    int ret = 0;
    uint32_t in_width;
    uint32_t in_height;

    stViInfo.stSnsInfo.u32SnsId     = IIC_BUS_NUMBER_1;
    stViInfo.stSnsInfo.u32PortId    = IIC_PORT_USI_10;
    stViInfo.stSnsInfo.u32BusId     = OV2732_SLAVE_ADDR_SID1;
    stViInfo.stSnsInfo.enFormat     = PIXEL_FORMAT_RAW10;
    stViInfo.stSnsInfo.enRes        = VEDEO_RES_1080P;
    stViInfo.stSnsInfo.u32MipiId    = MIPI_0;

    stViInfo.stPipeInfo.u32PipeId   = ISP_0;
    stViInfo.stPipeInfo.enFormat    = PIXEL_FORMAT_RAW8;
	stViInfo.stPipeInfo.enRes       = g_app_flow_cfg.enResIR;
    stViInfo.stPipeInfo.bIspBypass  = false;

    stViInfo.stLedInfo.enLightType  = LED_LIGHT_TYPE_RGB;

    tsm_vi_start(&stViInfo);    

    ov2732_init_rgb(&i2c_devices[stViInfo.stSnsInfo.u32SnsId], stViInfo.stSnsInfo.u32BusId);
    
    /* Without ISP, sensor should be configured mannully */
    if (stViInfo.stPipeInfo.bIspBypass)
    {
        imageChannel_t  iChn;
        
        iChn.in.format       = stViInfo.stSnsInfo.enFormat;
        iChn.in.res          = stViInfo.stSnsInfo.enRes;
        iChn.out.format      = stViInfo.stPipeInfo.enFormat;
        iChn.out.res         = stViInfo.stPipeInfo.enRes;
        iChn.mipi_ch         = stViInfo.stSnsInfo.u32MipiId;
        iChn.isp_ch          = stViInfo.stPipeInfo.u32PipeId;
        
        isp_config(iChn.isp_ch, &iChn.in, &iChn.out);
        //ret = ov2732_config(iChn.in);
        if (ret != 0) {
            printf("ov2732 config failed!\n");
        }
    }
    
    isp_res_map(stViInfo.stPipeInfo.enRes, &in_width, &in_height);
    config_RGB_left_90(stViInfo.stPipeInfo.u32PipeId, true, false, in_height, in_width);

    return ret;
}
#endif
int camera_ov2732_rgb_init()
{
    TSM_VI_INFO_S stViInfo = {0};
    int ret = 0;
    uint32_t in_width;
    uint32_t in_height;
    stViInfo.stSnsInfo.u32SnsId     = IIC_BUS_NUMBER_2;
    stViInfo.stSnsInfo.u32PortId    = IIC_PORT_USI_11;
    stViInfo.stSnsInfo.u32BusId     = OV2732_SLAVE_ADDR_SID1;
    stViInfo.stSnsInfo.enFormat     = PIXEL_FORMAT_RAW10;
    stViInfo.stSnsInfo.enRes        = VEDEO_RES_1080P;
    stViInfo.stSnsInfo.u32MipiId    = TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].mipi_id;
    stViInfo.stSnsInfo.u32MipiClk   = MIPI_CLK_350M_BPS_DEFAULT_XO;

    stViInfo.stPipeInfo.u32PipeId   = TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].isp_id;
    stViInfo.stPipeInfo.enFormat    = PIXEL_FORMAT_ARGB;//PIXEL_FORMAT_YUV_422;
    stViInfo.stPipeInfo.enRes       = g_app_flow_cfg.enResRGB;
    stViInfo.stPipeInfo.bIspBypass  = false;

    stViInfo.stPipeInfo.isp_flt_enable  = 0;
    stViInfo.stPipeInfo.denoise_level   = 0; // level: 0~10
    stViInfo.stPipeInfo.sharpen_level   = 0; // level: 0~10

    stViInfo.stPipeInfo.isp_cproc_enable    = 1;
    stViInfo.stPipeInfo.cproc_contrast      = 1.3; 
    stViInfo.stPipeInfo.cproc_brightness    = -25;
    stViInfo.stPipeInfo.cproc_saturation    = 1.0;    
    stViInfo.stPipeInfo.cproc_hue           = 0;

    stViInfo.stLedInfo.enLightType  = LED_LIGHT_TYPE_RGB;

    tsm_vi_start(&stViInfo);    

    ov2732_init_rgb(&i2c_devices[stViInfo.stSnsInfo.u32SnsId], stViInfo.stSnsInfo.u32BusId);
    
    /* Without ISP, sensor should be configured mannully */
    if (stViInfo.stPipeInfo.bIspBypass)
    {
        imageChannel_t  iChn;
        
        iChn.in.format       = stViInfo.stSnsInfo.enFormat;
        iChn.in.res          = stViInfo.stSnsInfo.enRes;
        iChn.out.format      = stViInfo.stPipeInfo.enFormat;
        iChn.out.res         = stViInfo.stPipeInfo.enRes;
        iChn.mipi_ch         = stViInfo.stSnsInfo.u32MipiId;
        iChn.isp_ch          = stViInfo.stPipeInfo.u32PipeId;
        
        isp_config(iChn.isp_ch, &iChn.in, &iChn.out);
        ret = ov2732_config(iChn.in);
        if (ret != 0) {
            printf("ov2732 config failed!\n");
        }
    }
    isp_rgb_buffer_reconfig(TX510_sensor_defConfig[IFV_SENSOR_TYPE_RGB].isp_id);
    
    isp_res_map(stViInfo.stPipeInfo.enRes, &in_width, &in_height);
    config_RGB_left_90(stViInfo.stPipeInfo.u32PipeId, true, false, in_height, in_width);

    return ret;
}

int camera_ov2732_ir_init()
{
    TSM_VI_INFO_S stViInfo = {0};
    int ret = 0;
    uint32_t in_width;
    uint32_t in_height;
    stViInfo.stSnsInfo.u32SnsId     = IIC_BUS_NUMBER_1;
    stViInfo.stSnsInfo.u32PortId    = IIC_PORT_USI_10;
    stViInfo.stSnsInfo.u32BusId     = OV2732_SLAVE_ADDR_SID1;
    stViInfo.stSnsInfo.enFormat     = PIXEL_FORMAT_RAW10;
    stViInfo.stSnsInfo.enRes        = VEDEO_RES_1080P;
    stViInfo.stSnsInfo.u32MipiId    = TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].mipi_id;
    stViInfo.stSnsInfo.u32MipiClk   = MIPI_CLK_550M_BPS_DEFAULT_XO;

    stViInfo.stPipeInfo.u32PipeId   = TX510_sensor_defConfig[IFV_SENSOR_TYPE_IR_LEFT].isp_id;
    stViInfo.stPipeInfo.enFormat    = PIXEL_FORMAT_RAW8;
    stViInfo.stPipeInfo.enRes       = g_app_flow_cfg.enResIR;
    stViInfo.stPipeInfo.bIspBypass  = false;

    stViInfo.stPipeInfo.isp_flt_enable  = 0;
    stViInfo.stPipeInfo.denoise_level   = 0; // level: 0~10
    stViInfo.stPipeInfo.sharpen_level   = 0; // level: 0~10

    stViInfo.stPipeInfo.isp_cproc_enable    = 0;
    stViInfo.stPipeInfo.cproc_contrast      = 1.0; 
    stViInfo.stPipeInfo.cproc_brightness    = 0;
    stViInfo.stPipeInfo.cproc_saturation    = 1.0;    
    stViInfo.stPipeInfo.cproc_hue           = 0;

    stViInfo.stLedInfo.u32LedId     = 2;
    stViInfo.stLedInfo.u32BusId     = CK_IIC_SLAVE_ADDR_IRLED;
    stViInfo.stLedInfo.enLightType  = LED_LIGHT_TYPE_IR;

    tsm_vi_start(&stViInfo);    

    ov2732_init(&i2c_devices[stViInfo.stSnsInfo.u32SnsId], stViInfo.stSnsInfo.u32BusId);
    
    /* Without ISP, sensor should be configured mannully */
    if (stViInfo.stPipeInfo.bIspBypass)
    {
        imageChannel_t  iChn;
        
        iChn.in.format       = stViInfo.stSnsInfo.enFormat;
        iChn.in.res          = stViInfo.stSnsInfo.enRes;
        iChn.out.format      = stViInfo.stPipeInfo.enFormat;
        iChn.out.res         = stViInfo.stPipeInfo.enRes;
        iChn.mipi_ch         = stViInfo.stSnsInfo.u32MipiId;
        iChn.isp_ch          = stViInfo.stPipeInfo.u32PipeId;
        
        isp_config(iChn.isp_ch, &iChn.in, &iChn.out);
        ret = ov2732_config(iChn.in);
        if (ret != 0) {
            printf("ov2732 config failed!\n");
        }
    }
    
    isp_res_map(stViInfo.stPipeInfo.enRes, &in_width, &in_height);
    config_IR_left_90(stViInfo.stPipeInfo.u32PipeId, true, false, in_height, in_width, 1);

    return ret;
}



int32_t sensor_standby(uint32_t isp_idx)
{
    //if (ISP_2 == isp_idx)
    {
        ov2732_mode_config(STANDBY);
    }
    
    aos_msleep(5);

    return 0;
}

int32_t sensor_stream(uint32_t isp_idx)
{
    //if (ISP_2 == isp_idx)
    {
        ov2732_mode_config(STREAM);
    }
    
    return 0;
}

int get_sensor_info_by_isp_idx(uint32_t idx, uint32_t *i2cNo, uint32_t *DevAddr)
{
    if (ISP_1 == idx)
    {
        *i2cNo = 0;
        *DevAddr = OV2732_SLAVE_ADDR_SID1;
    }
    else if (ISP_2 == idx)
    {
        *i2cNo = 1;
        *DevAddr = OV2732_SLAVE_ADDR_SID1;
    }

	//printf("id %d, i2cNo %d , devAdd %02x \n", idx, *i2cNo, *DevAddr);

    return 0;
}

void cfg_sensor_mi_buffer(uint8_t mode)
{
	isp_reg_write(ISP_0,MI_SP_Y_BASE_AD,   (uint32_t)iva_facereco_ir_get_buffer(0,0)); //0x1c2000
	isp_reg_write(ISP_0,MI_SP_Y_BASE_AD2,  (uint32_t)iva_facereco_temp_get_buffer());	
    isp_reg_write(ISP_0, MI_INIT, 0x10);
}

int sensor_reinit()
{
    return 0;
}

int sensor_reconfig(uint8_t mipi_ID, uint8_t mipiWorkMode_Flag)
{
    return 0;
}

void cfg_cat_eye_mi_buffer()
{
    return;
}

